import MatterManager from "../../managers/MatterManager";
import MatterBody from "./MatterBody";
import SnowBall from "./SnowBall";
import GamePlay from "../../model/GamePlay";
import IPointer from "../../interfaces/IPointer";
import GameInfo from "../../model/GameInfo";
import { GameStatusEnum } from "../../model/Enums";
import ConfigManager from "../../managers/ConfigManager";

export default class SnowMan extends MatterBody {


    /** @prop {name:snowBallPrefab,tips:"雪球",type:Prefab}*/
    snowBallPrefab: Laya.Prefab;

    /** @prop {name:width, tips:"宽度", type:Int, default:0}*/
    public width: number = 150;
    /** @prop {name:height, tips:"高度", type:Int, default:0}*/
    public height: number = 100;

    constructor() { super(); }

    speed: number = ConfigManager.initConfig.speed;
    snowManRadius = ConfigManager.initConfig.snowManRadius;
    snowBallRadius = ConfigManager.initConfig.snowBallRadius;
    angle = 0;
    isRebound = false;
    isMove = false;
    isRobot = false;
    realOwner: Laya.Sprite;
    snowBall: SnowBall;
    gameItem: any;

    lastSize = 25;
    itemScale = 1;

    onEnable(): void {
        let owner = this.owner as Laya.Sprite;
        this.realOwner = owner;

        this.body = this.matter.Bodies.circle(owner.x, owner.y, this.snowManRadius, {
            isStatic: false,
            friction: 0,
            frictionStatic: 0,
            frictionAir: 0.1,
            label: 'snowman'
        });

        this.gameItem = MatterManager.instance.bodyCreate({
            parts: [this.body],
            frictionAir: 0.2
        });
        MatterManager.instance.addToWorld(this.gameItem);

        if (this.isRobot) {
            setTimeout(() => {
                this.aiMove();
            }, 10);
        }
        super.onEnable();
    }

    onUpdate() {
        let isDie = this.checkDie();
        if (isDie) {
            this.removeBall();
            this.stopMove();
            if (this.isRobot) {
                this.realOwner.removeSelf();
            } else {
                GameInfo.instance.gameStatus = GameStatusEnum.GameOver;
            }
            return;
        }

        if (this.isRebound) {
            if (this.gameItem.velocity.x < 1 && this.gameItem.velocity.y < 1) {
                this.isRebound = false;
            }
            return;
        } else if (this.isMove) {
            let velocity = this.getVectorByAngle(this.angle, this.speed);
            MatterManager.instance.setVelocity(this.gameItem, velocity.x, velocity.y);
            MatterManager.instance.setAngle(this.gameItem, -this.angle)
        }

        super.onUpdate();
    }

    aiMove() {
        // ai  move            
        if (!this.isMove) {
            if (Math.random() < 0.2) {
                this.startMove();
            }
        } else {
            if (Math.random() < 0.05) {
                let angle = Math.random() * 8;
                this.changeDirection(angle);
            }
            if (Math.random() < 0.05) {
                this.stopMove();
            }
            let mapCenterPoint = GamePlay.instance.mapCenterPoint;
            let selfPoint: IPointer = {
                x: this.realOwner.x,
                y: this.realOwner.y
            }
            let mapRadius = GamePlay.instance.mapRadius;
            if (this.distanceOf2Point(mapCenterPoint, selfPoint) > mapRadius * 0.9) {
                let angle = Math.PI * 2 - Math.atan2(mapCenterPoint.y - selfPoint.y, mapCenterPoint.x - selfPoint.x)
                this.changeDirection(angle);
            }
        }


        let nextTime = Math.random() * 100;
        setTimeout(() => {
            this.aiMove();
        }, nextTime);
    }
    removeBall() {
        if (!this.snowBall || !this.snowBall.body) {
            return;
        }
        MatterManager.instance.compositeRemove(this.gameItem, this.snowBall.body);
        MatterManager.instance.removeFromWorld(this.snowBall.body);
        this.snowBall = null;
    }
    addBall() {
        if (!this.snowBallPrefab) {
            return;
        }
        if (this.snowBall) {
            return;
        }
        let snowBallSprite = this.snowBallPrefab.create();
        let distance = this.getVectorByAngle(this.angle, this.snowManRadius + this.snowBallRadius)
        snowBallSprite.pos(this.realOwner.x + distance.x, this.realOwner.y + distance.y);
        this.snowBall = snowBallSprite.getComponent(SnowBall) as SnowBall;

        // TODO 解决异步问题
        setTimeout(() => {
            if (!this.snowBall.body) {
                return;
            }
            MatterManager.instance.compositeAdd(this.gameItem, this.snowBall.body);
            this.snowBall.body = this.snowBall.body;
            this.snowBall.snowMan = this.body;
        }, 2);

        this.realOwner.parent && this.realOwner.parent.addChild(snowBallSprite);
    }

    startGrownUp() {
        Laya.timer.frameLoop(10, this, this.grownUp);
    }

    stopGrownUp() {
        Laya.timer.clear(this, this.grownUp);
        this.itemScale = 1;
        this.lastSize = 25;
    }

    grownUp() {
        if (!this.snowBall || !this.snowBall.body) {
            return;
        }
        this.lastSize = this.itemScale * 25;
        this.itemScale += 0.05;
        let targetSize = this.itemScale * 25;
        let distance = this.getVectorByAngle(this.angle, this.snowManRadius + targetSize);
        let point = {
            x: this.realOwner.x + distance.x,
            y: this.realOwner.y + distance.y
        };
        MatterManager.instance.setScaleToSize(this.snowBall.body, this.lastSize, targetSize);
        MatterManager.instance.setPosition(this.snowBall.body, point.x, point.y);
    }


    emit() {
        if (!this.snowBall || !this.snowBall.body) {
            return;
        }
        let ballPoint = {
            x: this.snowBall.body.position.x,
            y: this.snowBall.body.position.y
        }
        MatterManager.instance.compositeRemove(this.gameItem, this.snowBall.body);
        MatterManager.instance.removeFromWorld(this.snowBall.body);

        let ball = MatterManager.instance.matter.Bodies.circle(ballPoint.x, ballPoint.y, this.snowBall.body.circleRadius, {
            isStatic: false,
            isSensor: true,
            friction: 0,
            frictionStatic: 0,
            frictionAir: 0
        });
        MatterManager.instance.addToWorld(ball);
        this.snowBall.body = ball;
        let v = this.getVectorByAngle(this.angle, 10);
        MatterManager.instance.setVelocity(ball, v.x, v.y);
        this.snowBall = null;
    }

    checkDie(): boolean {
        let mapCenterPoint = GamePlay.instance.mapCenterPoint;
        let mapRadius = GamePlay.instance.mapRadius;
        let selfPoint: IPointer = {
            x: this.realOwner.x,
            y: this.realOwner.y
        }
        if (this.distanceOf2Point(selfPoint, mapCenterPoint) > mapRadius) {
            return true;
        }
        return false;
    }

    public onCollision(event) {
        this.isRebound = true;
        // this.body.frictionAir = 0.1;
        let other = this.getCollisitionPair(event.pairs);
        let angle = Math.atan2(this.body.position.y - other.position.y, this.body.position.x - other.position.x);
        angle = Math.PI * 2 - angle;

        let v = this.getVectorByAngle(angle, this.speed * 10);
        MatterManager.instance.setVelocity(this.body.parent, v.x, v.y);
    }


    public changeDirection(angle) {
        if (this.angle === angle || this.isRebound) {
            return;
        }
        this.angle = angle;
    }

    public startMove() {
        this.isMove = true;
        this.addBall();
        this.startGrownUp();
    }

    public stopMove() {
        this.isMove = false;
        this.stopGrownUp();
        this.setVelocity(0, 0);
        this.emit();
    }

    onDisable(): void {
        MatterManager.instance.removeFromWorld(this.gameItem);
    }

}